Repository navigation
correct: Say why the entry was invalid when suggesting a repair - #101
BenWestgate wants to merge 13 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b4d15aeeb6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
a7efaae to
054e8d9
Compare
This comment has been minimized.
This comment has been minimized.
054e8d9 to
115f2c2
Compare
e852899 to
dc4bf7b
Compare
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
BenWestgate
left a comment
There was a problem hiding this comment.
AI-generated review (Codex), posted at the maintainer's request.
Not ACKing 96ac5aa yet: this raises the installed-code budget from 5,200 to 5,250 without explicit authorization. The invalid-reason UX change otherwise looks sound.
96ac5aa to
dc4bf7b
Compare
This comment has been minimized.
This comment has been minimized.
BenWestgate
left a comment
There was a problem hiding this comment.
AI-generated current-head follow-up review (Codex), posted at the maintainer's request.
ACK dc4bf7bbc223 now that the unrelated <5250 cap commit has been removed.
The invalid-input reason is taken from the parse error the caller already caught, so the change does not add a second parsing/validation path. The message remains behind the existing low-discrimination disclosure gate, and the follow-up wording is profile-neutral (“same data”) rather than incorrectly assuming a wallet. The tested malformed-header/data/length and mixed-case cases cover the intended user-facing boundary.
No correctness blocker found in the focused behavior diff. The PR is stacked on #105 and preserves <5200; run final CI on the actual integrated #105 + #101 tip before freeze. Responsible-human authorship/review policy still applies.
This comment has been minimized.
This comment has been minimized.
BenWestgate
left a comment
There was a problem hiding this comment.
Codex current-head review at 65a886a: no findings. Since the prior ACK, the only new commit brings in #105’s already exact-head-reviewed cleanup; the invalid-reason behavior and disclosure-gate placement are unchanged.
BenWestgate
left a comment
There was a problem hiding this comment.
AI-generated current-head stack review (Codex), posted at the maintainer's request.
Code ACK 65a886a735b8 for the actual #105 + #101 head. #105 is now an ancestor of this branch; comparing #105 (361feb7) to the head yields only the four reviewed invalid-reason behavior/test files. The unrelated <5250 cap change is absent.
The reason text still comes from the already-caught parse error, remains behind the existing low-discrimination disclosure gate, and uses profile-neutral mixed-case wording. The known #104 call-shape overlap remains documented if that post-v1 enhancement is later integrated.
Fresh current-head Python-package run #755 is still queued at the time of this review. Treat this as an exact-head code ACK with CI pending. Responsible-human authorship/review still applies before integration.
|
V1 disposition (Codex, 2026-10-04): defer this post-audit UX enhancement from the v1 candidate. The invalid-reason behavior has a current-head Codex code ACK and fits under the library budget on #105. It is not required to close the original mixed-case audit finding, which is already fixed by #42. A temporary attempt to combine #100 and #101 exposed a real late-stack overlap conflict, so carrying this into v1 would enlarge the frozen-candidate review scope without closing an audit finding. Keep #101 open for post-v1, where it can be rebased with #100/#104 as appropriate. Human authorship/review remains required when integrated. |
03b0f8a to
9ea48de
Compare
CorrectionEdit was a plain dataclass, so repr() of a correction candidate disclosed each edit's observed and replacement characters. The replacement can be true recovery text. Exclude those two fields from dataclass repr while preserving explicit field access, equality, hashing, and correction behavior. Add a regression that repairs eight erasures and verifies the candidate representation does not reveal the restored characters. Fixes #129
core_descriptors(private=False) asked a named Bitcoin Core wallet for its HD key and built public descriptors from it, but only type-checked the seed it was given, so a wallet holding a different seed returned that wallet's descriptors. Nothing calls it: ms32 wallet hands Core the root xprv with addhdkey and Core builds the descriptors itself with createwalletdescriptor, and Core's listdescriptors and exportwatchonlywallet already provide public descriptors. We are pre-1.0, so delete public API that no command or tool calls instead of maintaining it: - core_descriptors, the WalletPublicDeriver protocol, the descriptor checksum (DESCSUM) and record helpers, and the Core adapter's public_descriptors, gethdkeys and derivehdkey calls; - generate_core_lightning_secret and CreationCeremony.core_lightning, which created fresh Core Lightning secrets that no command creates, and the CL padding check only fresh CL generation reached. Parsing, recovering, deriving and re-sharing an existing cl secret are unchanged. The real-Core fixture and installed-wheel smoke test now check xprv and tprv serialization through master_xprv. The package exports 22 names. The installed package drops from 5,196 to 4,965 logical lines. Fixes #128 Refs #63 Claude-Session: https://claude.ai/code/session_01T233rKgZqE5wzDm3EVTHL1
Fresh Core Lightning generation was removed from the public API, but the architecture, capability table, identifier policy, and security model still described it as supported. Align those contracts with the remaining behavior: existing CL secrets may still be parsed, recovered, corrected, derived, and re-shared.\n\nRefs #128
Core Lightning imports a codex32 HSM secret only when its threshold is 0 and its index is S; lightningd rejects anything else with "This is only one share of codex32!". The cl profile still parsed shares and shared S strings, CreationCeremony.from_secret split CL secrets, and the generic façade recovered and derived CL shares, so every CL share this library made or accepted was unusable in Core Lightning. Reject a nonzero threshold in the cl profile, which closes CL recovery, derivation and splitting at the parse boundary. The profile hook now receives the whole header instead of only the share index. Ceremonies accept only MasterSeed, so their profile plumbing goes away. Tests that only needed a valid CL secret use the BIP-93 cl10peev vector; the CL sharing fixtures and tests are removed, and new tests cover the rejections. The docs no longer promise CL sharing. Package size goes from 4,965 to 4,959 logical lines. Claude-Session: https://claude.ai/code/session_01T233rKgZqE5wzDm3EVTHL1
The identifier policy said a random identifier does not make a weak supplied seed safe. Nothing suggests it would; the sentence only invites the question. Claude-Session: https://claude.ai/code/session_01T233rKgZqE5wzDm3EVTHL1
The v1 rewrite dropped the license headers that master carries in bech32.py and checksums.py. bech32.py still derives convertbits from Pieter Wuille's segwit_addr.py, and checksums.py keeps his polymod arithmetic and Leon Olsson Curr and Pearlwort Sneed's codex32 generators. MIT and BSD-3-Clause both require the notice to travel with the code, and CONTRIBUTING.md requires the original author's header on derived work. Restore master's headers, except that checksums.py now credits the polymod arithmetic, since it no longer holds Bech32/Bech32m constants. Each credit also names its upstream source, sipa/bech32's ref/python/segwit_addr.py or BIP-93, as CONTRIBUTING.md asks. Comments do not count toward the package line budget. Claude-Session: https://claude.ai/code/session_01T233rKgZqE5wzDm3EVTHL1
The one-shot signature in api.md omitted generate_master_seed's fingerprint argument. A fresh call that leaves identifier unset raises ValueError unless that callable is supplied, so the documented defaults could not generate a seed. Show the argument and its contract. Claude-Session: https://claude.ai/code/session_01T233rKgZqE5wzDm3EVTHL1
WorksheetCorrection had the same repr leak as CorrectionEdit: for an erasure the worksheet filled with q, the addend is the recovered character itself, and for any other position it is the true character XOR the written one. Leave addend out of the generated repr; field access, equality and the CLI's explicit display are unchanged. Tighten the regression to compare exact reprs and to check that the repaired payload text does not appear. Refs #129 Claude-Session: https://claude.ai/code/session_01T233rKgZqE5wzDm3EVTHL1
The per-case CSV and kernel JSON (~9,900 lines) are generated records of an interrupted run that promoted no timing guarantee, and nothing in the package, tests or tools reads them. Keep the summary in alignment-benchmarks.md as informational guidance for setting correction limits on slower devices, drop its run-condition and source-hash details, point to the history for the raw JSON, and stop shipping docs *.csv/*.json in the sdist. Claude-Session: https://claude.ai/code/session_01MDsbGqZmvVThoJrs4vzc4K
Remove code from the substitution and erasure decoder that cannot change a result. Every BCH correction was re-checked against the full residue. The check cannot fail. The generator is the product of the distinct minimal polynomials of the 8 consecutive roots. GF(32) values that clear those syndromes also clear the conjugate roots, so the generator divides the corrected word. The linear erasure solver already rejects inconsistent systems. Delete _corrections_reach_target. The linear solver ran after a failed BCH decode even with at most 8 erasures. In that case an erasure-only solution leaves the Forney syndromes zero, so BCH would already have found it. Call the solver only when the erasures exceed the BCH roots. The worksheet path now makes the same choice inline, so _error_corrections is gone. Its word-length and substitution-limit parameters were unused. The precomputed erasure-product tables were never built. Remove that plumbing from _locator_poly, _bch_syndrome_corrections, _repair_body and _FixedCorrector. Also drop the no-op "except TypeError: raise" clauses. Keep the direct small-locator solve. Replacing it with Berlekamp-Massey for every call returned identical results but made the bounded indel search about 15% slower, which could change truncation under the ten- second deadline. Validation: full pytest in normal and -O modes; differential_correction and differential_wallet --verify; verify_correction_constants; ruff check, ruff format --check and mypy. An offline comparison against the previous module found identical results for random BCH syndromes, damaged ms strings with up to 14 errors or erasures, and worksheet residues with up to 15 erasures.
Old topic branches can retain superseded contribution rules, as happened while addressing PR #144 after #152 merged. Require agents to consult the current target-branch contributor guide and AI policy before acting on a PR. State that the tool-neutral policy permits AI-written descriptions and review replies while keeping publication within the user-authorized scope. The maintainer explicitly approved this AGENTS.md patch. Validation: reviewed the exact approved patch, checked referenced local paths, and ran git diff --check. Documentation only; application tests are not applicable. Refs #144 and #152.
`correct` and the "Possible correction" prompt in secret, share, wallet and create --existing showed only the repair. After the YES gate, print one line to stderr first, "Invalid: <reason>", using the first parse error the caller already caught, so nothing is parsed twice. The `reason` argument is keyword-only so it can't be swapped silently. A mixed-case string now says codex32 strings are all uppercase or all lowercase, and only that case alone doesn't change the encoded data: the same entry may also hold a wrong symbol, so the reason is not a full diagnosis. create --existing uses the same wording as the other commands. Closes #85 Claude-Session: https://claude.ai/code/session_015CuLXqAvAovfoVcUmmogwa Claude-Session: https://claude.ai/code/session_01Q1TNm1YeYW8K9W2eBvxmCD
65a886a to
ec065a3
Compare
|
Closing as not planned. When a correction is offered, the reason is almost always "The checksum does not match.", which the user already knows, and The tester's case question is answered in the user guide by #97: either case gives the same seed and fingerprint. Generated by Claude Code |
Requested by Ben · project thread
Problem
correct, and the embedded “Possible correction” prompt in recovery commands, showed a repaired string without first explaining why the entered text was invalid.Change
Print one
Invalid: <reason>line using the parse error already available to the caller. Mixed-case input uses the profile-neutral wording that codex32 strings are all uppercase or all lowercase and both cases decode to the same data. The reason is printed only after the low-discriminationYESgate, so noninteractive gate failure still emits only its operational error.The tested cases cover mixed case, invalid threshold/index symbols, invalid data characters, and an extra character.
create --existingkeeps using the library’s own rejection reason.Review stack
Base: #105 (
codex/remove-unreachable-v1-branches) at361feb7.The unrelated
<5250cap commit was removed and its old tip is preserved onarchive/101-pre-restack-20261004. #105 was merged into this feature branch through stack-maintenance PR #122, so current head65a886ais an actual descendant of #105. Comparing #105 to the head shows only the four reviewed behavior/test files.The combined tree is 5,188 installed production logical lines under
<5200. Exact-head Python-package run 755 succeeded on this combined head. #104 overlaps the_confirm_correctioncall shape and must preserve both arguments if #104 is later accepted.Validation
The behavior commit
dc4bf7bhas a Codex ACK. Prior validation passed 931 tests plus Ruff, strict mypy and focused optimized tests; exact-head Python-package run 755 is green. The review finding that the original mixed-case wording incorrectly said “same wallet” for non-wallet profiles is fixed.Closes #85.
AI-assisted stack maintenance and review. Responsible-human review/authorship policy still applies before integration.